package ai.ann.image.trainer;

import java.awt.Color;

import ai.ann.NeuralNetwork;
import ai.ann.Property;

import util.essential.VariableValueGetter;

public class ColorFactory {
	private static final VariableValueGetter valueGetter = new VariableValueGetter(Property.CONFIGURATION_FILE_NAME);
	private static final String COLOR_SPACE = ColorFactory.valueGetter.getStringValue("color_space");
	private static final boolean WITH_INPUT_DISTRIBUTION_FUCTION = ColorFactory.valueGetter.getStringValue("with_input_distribution_function").equals("true");
	private static final int CONSTANT = Integer.parseInt(ColorFactory.valueGetter.getStringValue("constant"));
	private static final int EXPONENT = Integer.parseInt(ColorFactory.valueGetter.getStringValue("exponent"));
	private static final String RGB = "RGB";
	private static final String HSI = "HSI";
	private static final short H = 360;
	private static final short S = 100;
	private static final short I = 255;
	public static long[] transformeTo(float a,float b,float c){
		float[]tmp={a,b,c};
		long[]ans = ColorFactory.transformeTo(tmp);
		if(ans!=null&&ColorFactory.WITH_INPUT_DISTRIBUTION_FUCTION){
			return ColorFactory.f(ans);
		}else{
			return ans;
		}
	}
	private static long[] transformeTo(float[]channel){
		long[]tmp=new long[3+((NeuralNetwork.WITH_ILUMINATION_CHANNEL)?1:0)];
		if(ColorFactory.RGB.equals(ColorFactory.COLOR_SPACE)){
			tmp[0]=(long)channel[0];
			tmp[1]=(long)channel[1];
			tmp[2]=(long)channel[2];
			if(NeuralNetwork.WITH_ILUMINATION_CHANNEL){
				/*float[]tmp2=new float[3];
				tmp2=Color.RGBtoHSB((int)channel[0],(int)channel[1],(int)channel[2], tmp2);
				tmp[3]=(long)(ColorFactory.I*tmp2[2]);*/
				tmp[3]=((tmp[0]+tmp[1]+tmp[2])/3);
			}
			return tmp;
		}else if(ColorFactory.HSI.equals(ColorFactory.COLOR_SPACE)){
			float[]tmp2=new float[3];
			tmp2=Color.RGBtoHSB((int)channel[0],(int)channel[1],(int)channel[2], tmp2);
			tmp[0]=(long)(ColorFactory.H*tmp2[0]);
			tmp[1]=(long)(ColorFactory.S*tmp2[1]);
			tmp[2]=(long)(ColorFactory.I*tmp2[2]);
			return tmp;
		}else return null;
	}
	public static long[] transformeFrom(float a,float b,float c){
		float[]tmp={a,b,c};
		long[]ans = ColorFactory.transformeFrom(tmp);
		if(ans!=null&&ColorFactory.WITH_INPUT_DISTRIBUTION_FUCTION){
			return ColorFactory.g(ans);
		}else{
			return ans;
		}
	}
	private static long[] transformeFrom(float[]channel){
		if(ColorFactory.HSI.equals(ColorFactory.COLOR_SPACE)){
			channel[0]=(channel[0]/ColorFactory.H);
			channel[1]=(channel[1]/ColorFactory.S);
			channel[2]=(channel[2]/ColorFactory.I);
			Color color = new Color(Color.HSBtoRGB(channel[0],channel[1],channel[2]));
			long[]tmp={(long)color.getRed(),(long)color.getGreen(),(long)color.getBlue()};
			return tmp;
		}else if(ColorFactory.RGB.equals(ColorFactory.COLOR_SPACE)){
			long[]tmp={(long)channel[0],(long)channel[1],(long)channel[2]};
			return tmp;
		}else return null;
	}
	private static long[] f(long[]x){
		long[]ans = new long[x.length];
		for (int i = 0; i < ans.length; i++) {
			ans[i] = (long) (ColorFactory.CONSTANT*Math.pow(x[i], ColorFactory.EXPONENT));
		}
		return ans;
	}
	private static long[] g(long[]x){
		long[]ans = new long[x.length];
		for (int i = 0; i < ans.length; i++) {
			ans[i] = (long) (Math.pow(((double)x[i]/(double)ColorFactory.CONSTANT), ((double)1/(double)ColorFactory.EXPONENT)));
			/*
			System.out.println("g("+x[i]+") = "+ans[i]);
			/**/
		}
		return ans;
	}
	//Test Main:
	public static void main(String[]args){
		System.out.println("RGB (255,255,255): ");
		long[]tmp = ColorFactory.transformeTo(255, 255, 255);
		for (int i = 0; i < tmp.length; i++) {
			System.out.print(tmp[i]+",");
		}
		System.out.println();
	}
}
